// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

import MatrixMap, { Eboundary } from '../utils/matrixMap'

@ccclass
export default class LsGame extends cc.Component {

    @property(cc.Node)
    layerReadyNode: cc.Node = null; // 开始页面

    @property(cc.Node)
    layerGameNode: cc.Node = null; // 游戏页面

    @property(cc.Node)
    layerZaitingNode: cc.Node = null; // 设置页面

    @property(cc.Node)
    starsBoxNode: cc.Node = null; // star父节点

    @property(cc.Prefab)
    starPrefab: cc.Prefab = null; // star预制体

    starXnum: number = 10 // 兵阵横向的数量
    starYnum: number = 10 // 兵阵粽向的数量
    starWh: number = 64 // 每一个兵的宽高，认定宽高一致
    starSpace: number = 2 // 相邻兵的间距
    starPositionSpace: number = 66 // 相邻兵坐标点的距离
    starsTotal: number = 100 // 兵总数

    selectArrTemp: number[] = [] // 临时存储选中的节点坐标

    matrixMap: MatrixMap = null;

    minSelectNum: number = 2; // 最少选中数量
    
    onLoad () {
        this.matrixMap = new MatrixMap();
        // console.log('load')
    }

    // start () {}

    // update (dt) {}

    /**
     * 点击开始按钮
     */
    onStartBtnClick(){
        this.onChangeLayerReadyNode(false)
        this.onChangeLayerGameNode(true)
        this.createStarsHandler();
    }

    /**
     * 点击暂停按钮
     */
     onStopBtnClick(){
        // this.onChangeLayerGameNode(false)
        this.onChangeLayerZaitingNode(true)
    }

    /**
     * 关闭设置
     */
     onCloseClick(){
        this.onChangeLayerGameNode(true)
        this.onChangeLayerZaitingNode(false)
    }

    /**
     * 返回主页
     */
     onGoHomeClick(){
        this.onChangeLayerZaitingNode(false)
        this.onChangeLayerGameNode(false)
        this.onChangeLayerReadyNode(true)
    }

    /**
     * 重新开始
     */
     onRestartClick(){
         cc.log('重新开始')
    }

    /**
     * 切换LayerReady节点的隐藏或显示
     * @param ac 
     */
    onChangeLayerReadyNode(ac: boolean){
        if(this.layerReadyNode){
            this.layerReadyNode.active = ac;
        }
    }

    /**
     * 切换LayerGane节点的隐藏或显示
     * @param ac 
     */
     onChangeLayerGameNode(ac: boolean){
        if(this.layerGameNode){
            this.layerGameNode.active = ac;
        }
    }

    /**
     * 切换layerZaiting节点的隐藏或显示
     * @param ac 
     */
     onChangeLayerZaitingNode(ac: boolean){
        if(this.layerZaitingNode){
            this.layerZaitingNode.active = ac;
        }
    }

    /**
     * 创建star
     */
    createStarsHandler(){
        if(!this.starPrefab){
            console.warn('缺少star prefab')
            return
        }
        if(!this.starsBoxNode){
            console.warn('缺少 stars box node')
            return
        }

        const boxw = this.starXnum * (this.starWh + this.starSpace) //父节点宽度
        const boxh = this.starYnum * (this.starWh + this.starSpace) // 父节点高度
        this.starsBoxNode.width = boxw
        this.starsBoxNode.height = boxh
        this.starsTotal = this.starXnum * this.starYnum;

        // 偏移量
        const offsetx = boxw / 2 - this.starWh / 2;
        const offsetY = offsetx

        // star基础相对坐标
        const startx = this.starWh + this.starSpace;
        const starty = startx
        this.starPositionSpace = startx;

        this.matrixMap.createMapArr({
            startx,
            starty,
            offsetx,
            offsetY
        })

        this.matrixMap.mapArr.forEach(item => {
            const star: cc.Node = cc.instantiate(this.starPrefab)
            star.x = item.pos.x;
            star.y = item.pos.y
            star.width = this.starWh
            star.height = this.starWh
            star.getComponent('soldierScript').initHandler(item.type)
            star.parent = this.starsBoxNode;
        })
        
        this.addLstenHandler()
    }

    /**
     * 添加监听事件
     */
    addLstenHandler(){
        this.starsBoxNode.on(cc.Node.EventType.TOUCH_START, (ev: cc.Event.EventTouch) => {
            const starPosOfWord = ev.getLocation(); // 获取点击点的世界坐标
            const starPosOfparent = this.starsBoxNode.convertToNodeSpaceAR(starPosOfWord) // 获取点击点相对于starsBoxNode的相对坐标
            const children = this.starsBoxNode.children;
            const len = children.length

            // 先清空上次的缓存
            this.matrixMap.clearSelectArrTemp();

            for(let i = 0; i < len; i++){
                const child = children[i]
                const childRect = child.getBoundingBox(); // 返回子节点相对于父节点的盒模型
                
                if(childRect.contains(starPosOfparent)){
                    // console.log(childRect, '选中了', child)
                    
                    // this.getAdjacentSpots(i)
                    const res = this.matrixMap.getAdjacentSpots(i)
                    if(res.length >= this.minSelectNum){
                        res.forEach((item: number) => {
                            const inode = children[item]
                            // inode.scale = 0.5
                            inode.getComponent('soldierScript').destroyHandler();
                        })
                    }
                    break
                }
            }
            
        })
    }

    /**
     * gie up 
     * 获取相邻的点集合
     */
    getAdjacentSpots(targetIndex: number){
        
        const children = this.starsBoxNode.children;
        const targetNode = children[targetIndex]
        const targetPos = targetNode.getPosition() // 获取节点相对坐标点
        const targetType: number = targetNode.getComponent('star').skinIndex;

        let arrx: number[] = [
            targetIndex,
            targetIndex + 1,
            targetIndex + this.starXnum,
            targetIndex - 1,
            targetIndex - this.starXnum
        ];
        
        arrx = arrx.filter((item: number) => {
            if(this.selectArrTemp.includes(item)){
                return false
            }
            if(item > 0 && item < this.starsTotal){
                const itemNode = children[item]
                const childPos = itemNode.getPosition();
                const disleng: number = childPos.sub(targetPos).mag() // 获取两个向量坐标点的距离
                const itemType: number = itemNode.getComponent('star').skinIndex;
                // 判断类型相同，距离合法，则命中
                if(itemType === targetType && disleng === this.starPositionSpace){
                    return true;
                }
            }
            return false;
        })
        
        arrx.forEach((item: number) => {
            this.selectArrTemp.push(item)
            this.getAdjacentSpots(item)
        })
    }
}
